

//#include "Timer_APP.h"
//#include <rtdevice.h>
#include <rtthread.h>

#include "main.h"
#include "water_quality.h" 
#include "Timer_APP.h"

#define DBG_TAG "TIMER"
#define DBG_LVL DBG_LOG 
#include <rtdbg.h>

/* ��Ϣ�����߳����ȼ�*/								
#define thread_MsgHandle_Prio 20 
/* ��Ϣ�����̵߳�������ƿ�*/
static struct rt_thread thread_TimerHandle; //ZGB��Ϣ�����߳� 
/* ��Ϣ�����̵߳�˽��ջ�ռ�*/
static rt_uint8_t thread_TimerHandle_stack[512]; //����Zigbee��Ϣ�����̵߳Ķ�ջ

#define ZGBLED_PIN_INDEX GET_PIN(B, 6)


#define LED_TIME_SLOT 		250 //100 //250
#define ONE_SEC_COUNT_SLOT 	4 //10 // 4
#define SELF_CHECK_SEC 		6
#define ONE_HOUR_SEC  		3600 // 60 *60=3600
#define TEN_MIN_COUNT_SEC  	600 // 60 *10=600
#define ONE_MIN_COUNT_SEC   60    // 1 * 60 =60
#define ONE_WEEK_SEC  604800 // 7 * 24 * 60 * 60 �� = 604800
#define ONE_DAY_SEC    		86400  // 24 * 60 *60 = 86400
#define FOUR_OCLOCK_SEC     14400  // 4 * 60 *60 = 14400
#define LED_STATE_CHANGE  	1
#define LED_STATE_KEEP    	0
#define ALL_CONDEV_QUERY_TIME 3000


#define STATUS_OFFLINE 	1

#define TIMER_FLAG 	(1 << 1)


static struct rt_event Timer100MSEvent;

static struct rt_timer timer_100MS;                                //���ٶ�ʱ���߳̿��ƿ�

extern int zigbee_status;
extern void ctrl_led(led_enum led, int action);
extern void Measure_TOC_action(void);
extern void TOC_Action(rt_uint8_t FLAG);
extern rt_uint8_t TOC_GetThreadState(void);
extern 	rt_int32_t adjustVolum;

/* ������LED �����һ��LED�࣬��������ṹ�����LED���һ��������״̬����*/
/* led ��״̬*/
struct led_state
{
	rt_uint8_t state ;		 /* ��ǰ״̬*/
	rt_uint8_t Final_state ; /* ���յ�״̬*/
	rt_uint16_t twink_number ; //0xff һֱ��˸
	rt_uint16_t interval_time ;/* ʱ����*/
	rt_uint16_t count_time ; 
	rt_uint8_t pin_index;
	
};
/* ����������*/
typedef struct led_state *led_state_t;
/* �ֱ������������ֱ�ָ��RS485LED��״̬��ZGBLED��״̬*/

struct led_state WQ_LED_State[LED_MAX_NUMB];

rt_uint32_t daySecTime = 0 ;
rt_uint32_t needMeasure = 0;

void TimerUpdateWqTestTime(rt_uint16_t time)
{
//	rt_uint16_t temp = time / LED_TIME_SLOT ;

//	wqMeasureTime = temp ;
//	LOG_I("delay full query time %d \n",time);

}

void LedInit(void)
{
	WQ_LED_State[LED_SYS_STATE].pin_index = LED_SYS;
	WQ_LED_State[LED_WIFI_STATE].pin_index = LED_SIG;
	WQ_LED_State[LED_TOC_MEASURE].pin_index = LED_TEST;
	WQ_LED_State[LED_WATER_FLOW].pin_index = LED_WATER;
	WQ_LED_State[LED_DEV_FAULT].pin_index = LED_FAULT;
	WQ_LED_State[LED_TDS_ALERT].pin_index = LED_TDS;
	WQ_LED_State[LED_TOC_ALERT].pin_index = LED_TOC;

}

void LedSwitch(rt_uint8_t state, rt_uint8_t pinIndx)
{
	ctrl_led(pinIndx,state);
}

/* 
twinkNumber = 0, keepTime = ����ֵ, decided by onOff (LED_ON: һֱ����LED_OFF��һֱϨ)
twinkNumber = LED_TWINK_FOREVER, keepTime�����þ� ȱʡ300ms һֱ��˸
twinkNumber ����ֵ����˸twinkNumber�Σ�ÿ��keeptimeʱ��(����),��˸����Ժ󣬰���onoffִ�С�

twinkNumber  ������0�����Ǵ����ƿ�ʼ��˸
*/


void LedAct(rt_uint8_t id,rt_uint8_t onOff,rt_uint32_t keepTime,rt_uint16_t twinkNumber) 
{
//	rt_mutex_take(timer_mutex,500);

    if(id>=LED_MAX_NUMB)
   		return;

//   LOG_I("LED start %d, %d, %d, %d\n",id,onOff,keepTime,twinkNumber);

    led_state_t pLedSate = &WQ_LED_State[id];


//	if(keepTime <= LED_TIME_SLOT)
//		pLedSate->interval_time = 0;
//	else
		pLedSate->interval_time = (int)keepTime/LED_TIME_SLOT;
	
	pLedSate->count_time = pLedSate->interval_time;
	pLedSate->twink_number = twinkNumber;
	pLedSate->Final_state = onOff;

	if(twinkNumber == 0)
		pLedSate->state = onOff;
	else
		pLedSate->state = LED_ON;

	LedSwitch(pLedSate->state,pLedSate->pin_index);


//	rt_mutex_release(timer_mutex);

	return;

}



static rt_uint8_t updateLedState(led_state_t pLedSate) // 
{
		if (pLedSate->twink_number > 0 ) //����
		{
			if(pLedSate->count_time !=0)
			{
				pLedSate->count_time--;				
			}

			if(pLedSate->count_time == 0)
			{			//����

//				LOG_I("thread Led_Zgb_count_time %d ; Led_Zgb_interval_time = %d ;  Led_Zgb_twink_number %d ; Led_Zgb_state %d \n",
//					Led_Zgb_count_time, Led_Zgb_interval_time,Led_Zgb_twink_number,Led_Zgb_state );

				pLedSate->count_time = pLedSate->interval_time;
				
				if(pLedSate->state == LED_OFF)
				{
					pLedSate->state = LED_ON;
				}
				else
				{
					pLedSate->state = LED_OFF;
				}

				if(pLedSate->twink_number != LED_TWINK_FOREVER)
				{		
					if(pLedSate->state == LED_OFF)
						pLedSate->twink_number--;
				}
				return LED_STATE_CHANGE;

			}

		}		
		else
		{
			if(pLedSate->count_time !=0)
			{
				pLedSate->count_time--;				
			}
			else if(pLedSate->state != pLedSate->Final_state)
			{
				pLedSate->state = pLedSate->Final_state;
				return LED_STATE_CHANGE;

			}
			
		}
		return LED_STATE_KEEP;

}


void timer_handle_entry(void *parameter)
{
    rt_err_t result = RT_EOK;
	led_state_t pLedSate;
	rt_uint8_t count = 0;
	rt_uint32_t secTime = 0 ;
	rt_uint32_t wqMeasureTime = 0; //�����ϴβ��Ե�ʱ�� ��λ��
	rt_uint32_t e,volum;

	LedInit();

	LOG_I("thread Led_Zgb_count_time");
	count = ONE_SEC_COUNT_SLOT;
	adjustVolum = WVL_getWaterLocalVolum();
	while(1)
	{
//		rt_thread_delay(LED_TIME_SLOT);
		result = rt_event_recv(&Timer100MSEvent, TIMER_FLAG,
                          RT_EVENT_FLAG_OR | RT_EVENT_FLAG_CLEAR,
                          RT_WAITING_FOREVER, &e);

  		if (result!= RT_EOK)
        {
        	LOG_D("toc msg get error %d \n",result);
            continue;
        }
                          

		/******  con dev query per 10 sec  *********/ 
		count++;
		if(count >= ONE_SEC_COUNT_SLOT) // 1 second
		{
			count = 0;			
			secTime++;
//			rt_kprintf(" %d ",secTime); 
			daySecTime++;
			if(daySecTime > ONE_DAY_SEC)//һ��:24*60*60=86400
			{
				daySecTime =0;
			}

			if((secTime % SELF_CHECK_SEC) == 0 ) // 6��һ���Լ�
			{
				if(wifiThreadSate == WQ_THREAD_IDLE)
				{
					WIFI_SendMessage(WQ_SELF_CHECK);
				}
			}

			if((secTime % ONE_MIN_COUNT_SEC) == 30 ) // 1����һ����������, ����10���wifi�������ͱ���
			{
				WIFI_SendMessage(WQ_KEEP_ALIVE);
			}
			

			// 1��У׼һ��,��һ����ˮû�г���150L
			// ���߾����ϴ�У׼��ˮ������150L
			volum = WVL_getWaterLocalVolum();
			if((secTime % ONE_WEEK_SEC) == 0 || volum - adjustVolum > 150)
			{												  	
				secTime = 0; 									
				TOC_Action(TOC_ADJUST_FLAG);
			}

			//������׼->�����ϴβ���:����1��Сʱ������ˮ�ˣ����߳���1��û����ˮ
			wqMeasureTime++;
			if(wqMeasureTime > ONE_HOUR_SEC )// ����1��Сʱ 
			{
				if(needMeasure > 30) //�ù�ˮ�������Ѿ��رգ�����30��û����ˮ��
				{
					wqMeasureTime = 0;
					needMeasure = 0;
					TOC_Action(TOC_MEASURE_FLAG);

				}
				else
				{
					volum = WVL_getWaterIntervalVolum();
					if(wqMeasureTime > ONE_DAY_SEC) //һֱû����ˮ����1��
					{
						wqMeasureTime = 0;
						needMeasure = 0;
						TOC_Action(TOC_MEASURE_FLAG);
					}
					else if(volum > PULSE_ONE_L * 100) //һֱ������ˮ��
					{
						wqMeasureTime = 0;
						needMeasure = 0;
						TOC_Action(TOC_MEASURE_FLAG);
					}					
				 }
			}
		}


		/******  ZGB led *********/ 
//rt_mutex_take(timer_mutex,500);

		for(int i=0;i<LED_MAX_NUMB;i++)
		{
			pLedSate = &WQ_LED_State[i];
	
			if(updateLedState(pLedSate) == LED_STATE_CHANGE)
				LedSwitch(pLedSate->state,pLedSate->pin_index);

//		if(pLedSate->state == LED_OFF)
//			zigbee_status = STATUS_OFFLINE;

		}

//rt_mutex_release(timer_mutex);

	}

}

static void TIM_100MSTimer(void *parameter)
{
	rt_event_send(&Timer100MSEvent, TIMER_FLAG);

}

int Timer_init(void)
{

    rt_event_init(&Timer100MSEvent, "event", RT_IPC_FLAG_PRIO);

	
   /*����100MS��ʱ���߳�*/	
   rt_timer_init(&timer_100MS,
				 "WVL_timer_water_speed",
				  TIM_100MSTimer,
				  0,
				  252, //100, //252,                               //��ʱ����100��ϵͳʱ��(0.1����)
				  RT_TIMER_FLAG_PERIODIC);				              //��ʱ�����ڼ�ʱ
       rt_timer_start(&timer_100MS);                            //������ʱ��				  
	
    rt_thread_init(&thread_TimerHandle,
                   "TimerHandleThread",
                   timer_handle_entry,
                   RT_NULL,
                   thread_TimerHandle_stack,
                   sizeof(thread_TimerHandle_stack),
                   thread_MsgHandle_Prio,
                   5);
    rt_thread_startup(&thread_TimerHandle);
    return 0;
}
//INIT_APP_EXPORT(Timer_init);
